'''BeautifulSoup 基本使用'''
'''用于解析 HTML文档内容的第三方库'''
from bs4 import BeautifulSoup as bs
'''初始化 html内容'''
html = '''
<html>
    <head>
        <title>这是标题The Dormouse's story</title>
    </head>
<body>
    <div>
        <p class="">
            <a href="baidu">百度1下</a>
            <a href="baidu">百度2下</a>
            <a href="baidu">百度3下</a>
        </p>
    </div>
    <p class="title"><b>The Dormouse's story</b></p>
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    <p class="story">...</p>
    <ur>
    <li class='item item1'>第1项</li>
    <li class='item item1 item2'>第2项</li>
    <li class='item item1 item2'>第3项</li>
    <li class='item item2 item1'>第4项</li>
    <li class='item'>第5项</li>
    </ur>
</body>
</html>
'''

'''初始化 bs4的对象'''
soup = bs(html, 'html.parser')
'''通过 .prettify()可以得到一个整理过后规范的标准的HTML文档'''
print(soup.prettify())
'''实例化后的 BeautifunlSoup 对象将HTML文档转换为一个 虚拟DOM树
树的分支点称之为 节点，每一个节点都是一个Python对象
一共有4种对象'''
'''1.Tag 标签对象
Tag 与 HTML 原生文档中的标签名字相同 tag == 标签
'''
print(soup.title)
print(soup.p)#只能拿第一个
print(soup.a)
print(type(soup.a))#bs 中的类
'''首先通过BS类的实例  soup.tag的形式  选取 对应的标签名称
只能选中对应标签中的 第一个
Tag 中重要的属性有2个   name，attributes'''
'''Name 每一个Tag都有自己的名字,通过 .name 进行获取'''
print(soup.p.naem)

'''bs也可通过 name 修改对应的 name'''
# soup.p.naem = 'div'
# print(soup.prettify())#原文件不会更改 只是更改虚拟的Dom树

'''Attributes 属性 对等的是 HTML元素的 行内属性 比如 id class '''
print(soup.p['class'])
print(soup.p.attrs)
print(soup.a.attrs)
'''2.NavigableString 获取标签的内容'''
#当节点（包含很多标签的标签）中除了包含的标签还有自己的内容 就不是一个纯节点
#  不能获取其中的内容 如下 head
print(soup.head.string)#None
print(soup.title.string)#这是标题The Dormouse's story
print(soup.p.string)#The Dormouse's story
'''3.遍历文档树'''
'''3.1子节点
通过 Tag的name 来遍历
'''
print(soup.head.title)
print(soup.find_all('a'))
for item in soup.find_all('a'):
    print(type(item))
    print(item.attrs)
    print(item.string)
'''3.2 .contents 和 .children
这2个属性仅包含tag 的直接子节点'''
'''.contents 属性可以将tag的子节点以列表的方式输出'''
print(soup.html.contents)
'''.children 属性可以将tag的字节点以迭代器的方式输出'''
print(soup.html.children)
for index,child in enumerate(soup.html.children):
    print(index,child)
'''.descendants 属性可以对 tag 下所有的子节点进行递归遍历'''
for index,child in enumerate(soup.html.descendants):
    print(index,child)
'''3.3 .parents 父辈节点'''
print(soup.a.parents)
for item in soup.a.parents:
    if item is None:
        print(item)
    else:
        print(item.name)
print(soup.name)
'''.parent 父节点'''
print(soup.a.parents)

'''3.4 兄弟节点'''
'''
.next_silbing 和 .previous_sibling
都是往上或者往下各找一个

.nex_siblings 和 .previous_sibling
都会生成一个迭代器，分别对 遍历的方向的元素进行迭代 直到找不到为止'''
for item in soup.a.next_siblings:
    print('item:',repr(item))

'''4.过滤器'''
'''4.1 字符串过滤器'''
# print(soup.find_all('a'))#这种找到所有的
for index, item in enumerate(soup.div.p.find_all('a')):
    print(index,item)
'''4.2 正则表达式'''
import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
'''对文档中所有的文字进行正则对比'''
print(soup.find(text=re.compile('sisters')))
# print(soup.find_all(text=re.compile('sisters')))
# #返回的是列表  把含有'sisters'的每一项都输出了
'''对文档中所有的属性中指定的属性进行正则'''
print(soup.find_all(href=re.compile('elsie'),id='link1',class_='sisters'))

'''对特殊属性的匹配  例如 ：html5 中的新属性 data-*'''
print(soup.find_all(attrs={'data-abc': re.compile('^abc+$')}))
# '''4.3列表方式'''
# # string 只对纯字符串 或者纯标签的节点有效  否则输出 None
# for tag in soup.find_all(['a','b']):
#     print(tag.name,tag.string)
# for tag in soup.find_all('p','title'):
#     print(tag.name,tag.string)
# for tag in soup.find_all('p','story',limit=1):
#     print(tag.name,tag.string)
#     for item in tag.find_all('a'):
#         print(item.name,item.string)
# '''find()查找当前 匹配条件满足的第一个元素'''
# print(soup.find(id='link1'))#找页面ID  每个页面有且只有一个ID
# '''id=True 表示 找到带有id 属性的元素 并且 id的值是有效的'''
# print(soup.find(id=True))#find()方法只能找第一个   find_all()找到所有的
# '''4.4按CSS的属性进行过滤'''
# '''此方式是BS4 版本之后方式  引入一个关键字 class_'''
# print(soup.find_all('li',class_='item item1 item2'))
#
#
# '''
# HTML是web页面
# '''
